#pragma once


namespace WorldWind
{
	/// <summary>
	/// Summary description for Point3d.
	/// </summary>
	typedef struct Point2d
	{
		double X, Y;
		// constructors

		 Point2d()
		{

		}

		Point2d (double xi, double yi)	// x,y constructor
		{
			X = xi; Y = yi;
		}
		Point2d (const Point2d& P) // copy constructor
		{
			X = P.X;
			Y = P.Y;
		}

		// other operators
		 double norm()	// L2 norm
		{
			return sqrt(norm2());
		}

		 double norm2() // squared L2 norm
		{
			return X*X + Y*Y;
		}

		 Point2d normalize() // normalization
		{
			double n = norm();
			return Point2d(X / n, Y / n);
		}

		 double Length()
		 {
			 return sqrt(X * X + Y * Y);
		 }


		
		// Override the Object.Equals(object o) method:
// 		 override bool Equals(object o)
// 		{
// 			try
// 			{
// 				return (bool)(this == (Point2d)o);
// 			}
// 			catch
// 			{
// 				return false;
// 			}
// 		}

		// Override the Object.GetHashCode() method:
		int GetHashCode()
		{
			//not the best algorithm for hashing, but whatever...
			return (int)(X * Y);
		}
		friend Point2d operator +(Point2d P1, Point2d P2);	// addition 2
		friend Point2d operator -(Point2d P1, Point2d P2);	// subtraction 2

		friend Point2d operator *(Point2d P, double k);	// multiply by real 2

		friend Point2d operator *(double k, Point2d P);	// and its reverse order!

		friend Point2d operator /(Point2d P, double k);	// divide by real 2
		 friend bool operator ==(Point2d P1, Point2d P2) ;// equal?

		 friend bool operator !=(Point2d P1, Point2d P2) ;// equal?

		static double dot(Point2d P1, Point2d P2) // inner product 2
		{
			return (P1.X * P2.X + P1.Y * P2.Y);
		}
		//	TODO: implement this...
		//	 static Point2d operator *(Point2d P1, Point2d P2)
		//	{
		//		return new Point2d (P1.Y * P2.Z - P1.Z * P2.Y,
		//			P1.Z * P2.X - P1.X * P2.Z, P1.X * P2.Y - P1.Y * P2.X);
		//	}

		 friend Point2d operator - ( Point2d P);	// negation

		//	 static Point3d cross(Point2d P1, Point2d P2) // cross product
		//	{
		//		return P1 * P2;
		//	}

		// Normal direction corresponds to a right handed traverse of ordered points.
		//	 Point2d unit_normal (Point2d P0, Point2d P1, Point2d P2)
		//	{
		//		Point2d p = (P1 - P0) * (P2 - P0);
		//		double l = p.norm ();
		//		return new Point2d (p.X / l, p.Y / l);
		//	}
	}Point2d;
	Point2d operator +(Point2d P1, Point2d P2)	// addition 2
	{
		return Point2d (P1.X + P2.X, P1.Y + P2.Y);
	}

	Point2d operator -(Point2d P1, Point2d P2)	// subtraction 2
	{
		return Point2d (P1.X - P2.X, P1.Y - P2.Y);
	}

	Point2d operator *(Point2d P, double k)	// multiply by real 2
	{
		return Point2d (P.X * k, P.Y * k);
	}

	Point2d operator *(double k, Point2d P)	// and its reverse order!
	{
		return Point2d (P.X * k, P.Y * k);
	}

	Point2d operator /(Point2d P, double k)	// divide by real 2
	{
		return Point2d (P.X / k, P.Y / k);
	}

	bool operator ==(Point2d P1, Point2d P2) // equal?
	{
		return (P1.X == P2.X && P1.Y == P2.Y);
	}

	bool operator !=(Point2d P1, Point2d P2) // equal?
	{
		return (P1.X != P2.X || P1.Y != P2.Y);
	}

	Point2d operator - ( Point2d P)	// negation
	{
		return Point2d (-P.X, -P.Y);
	}
}
